package per.chao.mqtt.domain.protocol;

import com.google.common.collect.Maps;
import io.netty.handler.codec.mqtt.MqttMessageType;
import org.springframework.stereotype.Component;
import per.chao.mqtt.domain.protocol.connect.Connect;
import per.chao.mqtt.domain.protocol.disconnect.DisConnect;
import per.chao.mqtt.domain.protocol.pingreq.PingReq;
import per.chao.mqtt.domain.protocol.puback.PubAck;
import per.chao.mqtt.domain.protocol.pubcomp.PubComp;
import per.chao.mqtt.domain.protocol.publish.Publish;
import per.chao.mqtt.domain.protocol.pubrec.PubRec;
import per.chao.mqtt.domain.protocol.pubrel.PubRel;
import per.chao.mqtt.domain.protocol.subscribe.Subscribe;
import per.chao.mqtt.domain.protocol.unsubscribe.UnSubscribe;

import javax.annotation.PostConstruct;
import javax.annotation.Resource;
import java.util.Map;

/**
 * Description:
 *
 * @author W.Chao
 * @date 2021/6/20 11:40
 **/
@Component
public class ProtocolTransportMap {
	private Map<MqttMessageType, BaseProtocolHandler> protocolMap = Maps.newConcurrentMap();

	@Resource
	private Connect connect;
	@Resource
	private DisConnect disConnect;
	@Resource
	private PingReq pingReq;
	@Resource
	private Publish publish;
	@Resource
	private PubAck pubAck;
	@Resource
	private PubRel pubRel;
	@Resource
	private PubRec pubRec;
	@Resource
	private PubComp pubComp;
	@Resource
	private Subscribe subscribe;
	@Resource
	private UnSubscribe unSubscribe;

	@PostConstruct
	public void initProtocolMap() {
		protocolMap.put(MqttMessageType.CONNECT, connect);
		protocolMap.put(MqttMessageType.DISCONNECT, disConnect);
		protocolMap.put(MqttMessageType.PINGREQ, pingReq);
//		protocolMap.put(MqttMessageType.PINGRESP, connect); // 服务器不需要处理ping响应类型消息
		protocolMap.put(MqttMessageType.PUBLISH, publish);
		protocolMap.put(MqttMessageType.PUBACK, pubAck);
		protocolMap.put(MqttMessageType.PUBREC, pubRec);
		protocolMap.put(MqttMessageType.PUBREL, pubRel);
		protocolMap.put(MqttMessageType.PUBCOMP, pubComp);
		protocolMap.put(MqttMessageType.SUBSCRIBE, subscribe);
		protocolMap.put(MqttMessageType.UNSUBSCRIBE, unSubscribe);
	}

	/**
	 * 根据消息类型获取协议处理器
	 *
	 * @param type
	 * @return
	 */
	public BaseProtocolHandler getProtocol(MqttMessageType type) {
		if (!protocolMap.containsKey(type)) {
			throw new IllegalArgumentException("not support mqtt protocol, arg: " + type.name());
		}
		return protocolMap.get(type);
	}
}
